<template>
  <a-modal
      title="作品上传/编辑"
      v-model:visible="visible"
      @ok="handleOk"
      :okButtonProps="{ disabled: !isReady || isUploading }"
      @cancel="handleCancel"
      width="800px"
      :confirmLoading="isUploading"
  >
    <a-form layout="vertical" :model="formState" ref="formRef">
      <!-- 作品标题 -->
      <a-row :gutter="24">
        <a-col :span="12">
          <a-form-item label="作品标题" name="worksName">
            <a-input
                v-model:value="formState.worksName"
                placeholder="请输入作品标题"
                :maxlength="200"
                show-count
            />
          </a-form-item>
        </a-col>
      </a-row>

      <!-- 收费设置 -->
      <a-row :gutter="24">
        <a-col :span="12">
          <a-form-item label="是否收费">
            <a-switch
                v-model:checked="formState.isCharge"
                checked-children="收费"
                un-checked-children="免费"
                @change="handleChargeChange"
            />
          </a-form-item>
        </a-col>
        <a-col :span="12" v-if="formState.isCharge">
          <a-form-item label="价格" name="price">
            <a-input-number
                v-model:value="formState.price"
                :min="0.01"
                :max="999999.99"
                :precision="2"
                style="width: 100%"
                placeholder="请输入价格"
            />
          </a-form-item>
        </a-col>
      </a-row>

      <!-- 封面上传 -->
      <a-form-item label="作品封面" name="cover" class="cover-upload-item">
        <div class="cover-upload-container">
          <a-upload
              v-model:file-list="coverFiles"
              list-type="picture-card"
              :max-count="1"
              :before-upload="beforeUploadCover"
              :customRequest="handleCoverUpload"
              accept="image/jpeg,image/png,image/webp"
              :showUploadList="{
              showPreviewIcon: true,
              showRemoveIcon: true,
              showDownloadIcon: false
            }"
              @preview="handlePreview"
              @remove="handleCoverRemove"
          >
            <div v-if="coverFiles.length < 1" class="upload-placeholder">
              <plus-outlined />
              <div class="upload-text">上传封面</div>
            </div>
          </a-upload>
        </div>
        <a-form-error v-if="coverUploadError" class="cover-upload-error">{{ coverUploadError }}</a-form-error>
      </a-form-item>

      <!-- 作品描述 -->
      <a-form-item label="作品描述">
        <a-textarea
            v-model:value="formState.description"
            placeholder="请输入作品描述"
            :rows="4"
            show-count
            :maxlength="500"
        />
      </a-form-item>

      <!-- 标签选择 -->
      <a-form-item label="标签" name="tagIds">
        <a-select
            v-model:value="formState.tagIds"
            mode="multiple"
            style="width: 100%"
            placeholder="请从下拉框选择标签（最多5个）"
            :options="tagOptions"
            :max-tag-count="5"
            allow-clear
        >
          <template #notFoundContent>
            <div>没有找到相关标签</div>
          </template>
        </a-select>

        <p class="tag-hint" v-if="tagStore.hotTags.length > 0">
          热门标签：
          <a-tag
              v-for="tag in tagStore.hotTags"
              :key="tag.id"
              @click="addTagById(tag.id)"
              :closable="false"
              style="margin: 0 4px 4px 0; cursor: pointer;"
          >
            {{ tag.name }}
          </a-tag>
        </p>

        <a-spin size="small" v-if="tagStore.isLoading" style="margin-top: 8px;" />
        <a-form-error v-if="tagStore.error" style="margin-top: 4px;">
          {{ tagStore.error }}
        </a-form-error>
      </a-form-item>

      <!-- 视频上传 -->
      <a-form-item label="作品视频" name="video">
        <VideoUploader
            ref="videoUploader"
            :disabled="isUploading"
            @fileSelected="handleFileSelected"
            @uploadComplete="handleUploadComplete"
            @uploadError="handleUploadError"
            @fileRemoved="handleFileRemoved"
        />
        <p v-if="props.editWork?.videoUrl" class="video-hint">
          已上传视频：{{ props.editWork.videoUrl.split('/').pop() || '未知视频' }}
        </p>
      </a-form-item>
    </a-form>
  </a-modal>

  <!-- 图片预览模态框 -->
  <a-modal :visible="previewVisible" :footer="null" @cancel="previewVisible = false">
    <img alt="封面预览" :src="previewImage" style="width: 100%" />
  </a-modal>
</template>

<script setup lang="ts">
import { ref, computed, reactive, onMounted } from 'vue';
import { message } from 'ant-design-vue';
import { PlusOutlined } from '@ant-design/icons-vue';
import type { UploadProps, FormInstance } from 'ant-design-vue';
import type { Work } from './WorksManager.vue'; // 引入作品类型

// 组件导入
import VideoUploader from './VideoUploader.vue';

// API导入
import { uploadPic } from '@/api/media/bizFilesController';
import { createWorks, updateWorks } from '@/api/media/bizWorksController';

// Pinia Store导入
import { useTagStore } from '@/stores/worksTagStore';

// 接收父组件传入的待编辑作品
const props = defineProps<{
  editWork?: Partial<Work>;
}>();

// 表单状态
interface FormState {
  worksName: string;
  coverFileUrl?: string;
  description: string;
  tagIds: number[];
  isCharge: boolean;
  price: number | null;
  fileMd5?: string;
}

const formState = reactive<FormState>({
  worksName: '',
  description: '',
  tagIds: [],
  isCharge: false,
  price: null,
});

// 其他状态变量
const formRef = ref<FormInstance>();
const visible = ref(false);
const previewVisible = ref(false);
const previewImage = ref('');
const isCoverUploading = ref(false);
const coverUploadError = ref('');
const isUploading = ref(false);
const hasVideo = ref(false);
const uploadResult = ref<{ fileMd5: string; fileName: string } | null>(null);
const coverFiles = ref<UploadProps['fileList']>([]);
const videoUploader = ref<InstanceType<typeof VideoUploader>>();
const tagStore = useTagStore();

// 组件挂载时加载标签
onMounted(() => {
  if (tagStore.tags.length === 0) {
    tagStore.fetchAndSaveTags();
  }
});

// 封面上传前校验
const beforeUploadCover: UploadProps['beforeUpload'] = (file) => {
  coverUploadError.value = '';
  const isImage = file.type.startsWith('image/');
  if (!isImage) {
    coverUploadError.value = '只能上传图片文件!';
    return false;
  }
  const isLt5M = file.size / 1024 / 1024 < 5;
  if (!isLt5M) {
    coverUploadError.value = '图片大小不能超过5MB!';
    return false;
  }
  return true;
};

// 处理封面上传
const handleCoverUpload: UploadProps['customRequest'] = async (options) => {
  const { file, onSuccess, onError } = options;
  isCoverUploading.value = true;

  try {
    const response = await uploadPic({}, file as File);
    if (response.code === '00000' && response.data) {
      formState.coverFileUrl = response.data.previewUrl;
      onSuccess(response.data, file);
      message.success('封面上传成功');
    } else {
      throw new Error(response.message || '封面上传失败');
    }
  } catch (error) {
    const errMsg = error instanceof Error ? error.message : '封面上传失败';
    coverUploadError.value = errMsg;
    onError(new Error(errMsg));
  } finally {
    isCoverUploading.value = false;
  }
};

// 封面预览
const handlePreview = (file: UploadProps['file']) => {
  previewImage.value = file.url || '';
  previewVisible.value = true;
};

// 移除封面
const handleCoverRemove = () => {
  formState.coverFileUrl = undefined;
  coverUploadError.value = '';
};

// 收费状态切换
const handleChargeChange = (checked: boolean) => {
  if (!checked) {
    formState.price = null;
  }
};

// 标签选择器选项
const tagOptions = computed(() => {
  return tagStore.tags.map(tag => ({
    label: tag.name,
    value: tag.id
  }));
});

// 快速添加标签
const addTagById = (tagId: number) => {
  if (formState.tagIds.includes(tagId)) return;
  if (formState.tagIds.length >= 5) {
    message.warning('最多只能选择5个标签');
    return;
  }
  formState.tagIds.push(tagId);
};

// 提交状态判断
const isReady = computed(() => {
  return (
      !!formState.worksName &&
      hasVideo.value &&
      !!formState.coverFileUrl &&
      formState.tagIds.length > 0 &&
      (!formState.isCharge || (formState.isCharge && formState.price !== null))
  );
});

// 视频事件处理
const handleFileSelected = () => {
  hasVideo.value = true;
};

const handleFileRemoved = () => {
  hasVideo.value = false;
  uploadResult.value = null;
};

const handleUploadComplete = (data: { fileMd5: string; fileName: string }) => {
  uploadResult.value = data;
  formState.fileMd5 = data.fileMd5;
  message.success('视频上传完成');
};

const handleUploadError = (error: string) => {
  message.error(`上传失败：${error}`);
};

// 提交作品
const emit = defineEmits(['success', 'fail', 'refresh']);
const handleOk = async () => {
  if (!formRef.value) return;

  try {
    await formRef.value.validate();
    isUploading.value = true;

    // 确保视频上传完成（新增时）
    if (!props.editWork && !uploadResult.value) {
      await videoUploader.value?.startUpload();
      if (!uploadResult.value) {
        throw new Error('视频上传未完成，请稍后重试');
      }
    }

    // 构建接口参数
    const submitParams = {
      bizWorks: {
        id: props.editWork?.id, // 编辑时传递
        worksName: formState.worksName,
        description: formState.description,
        coverFileUrl: formState.coverFileUrl,
        tags: formState.tagIds.join(','), // 数组转字符串
        isCharge: formState.isCharge ? 1 : 0, // 布尔值转整数
        price: formState.price,
        fileMd5: uploadResult.value?.fileMd5 || formState.fileMd5, // 编辑时用原视频MD5
        status: 1 // 默认为草稿状态
      }
    };

    // 区分新增和编辑
    let response;
    if (props.editWork?.id) {
      response = await updateWorks(submitParams); // 编辑接口
    } else {
      response = await createWorks(submitParams); // 新增接口
    }

    if (response.code === '00000') {
      const action = props.editWork ? '编辑' : '创建';
      message.success(`${action}作品成功`);
      emit('success', response.data);
      emit('refresh'); // 通知父组件刷新列表
      visible.value = false;
    } else {
      throw new Error(response.message || `${props.editWork ? '编辑' : '创建'}作品失败`);
    }
  } catch (error) {
    if ((error as FormValidateError).errorFields) {
      const validateError = error as FormValidateError;
      const errorMsg = validateError.errorFields.map(field => {
        const fieldName = field.name.join('');
        const fieldLabelMap: Record<string, string> = {
          worksName: '作品标题',
          price: '价格',
          cover: '作品封面',
          video: '作品视频',
          tagIds: '标签'
        };
        const fieldLabel = fieldLabelMap[fieldName] || fieldName;
        return `${fieldLabel}：${field.errors.join('; ')}`;
      }).join('；');
      message.error(`请完善以下信息：${errorMsg}`);
    } else {
      const errorMsg = error instanceof Error ? error.message : '操作失败，请重试';
      message.error(errorMsg);
      emit('fail', errorMsg);
    }
  } finally {
    isUploading.value = false;
  }
};

// 取消操作
const handleCancel = () => {
  resetForm();
  visible.value = false;
  emit('refresh'); // 可选：取消时也刷新
};

// 重置表单
const resetForm = () => {
  formRef.value?.resetFields();
  coverFiles.value = [];
  previewVisible.value = false;
  hasVideo.value = false;
  isUploading.value = false;
  uploadResult.value = null;
  coverUploadError.value = '';
  formState.coverFileUrl = undefined;
  formState.tagIds = [];
  videoUploader.value?.clear();
};

// 打开弹窗（支持传入编辑数据）
const open = (work?: Partial<Work>) => {
  visible.value = true;
  resetForm();

  if (work) {
    // 回显编辑数据
    formState.worksName = work.worksName || '';
    formState.description = work.description || '';
    formState.isCharge = work.isCharge === 1;
    formState.price = work.price || 0;
    formState.coverFileUrl = work.coverFileUrl;
    formState.fileMd5 = work.fileMd5;

    // 标签回显（字符串转数组）
    formState.tagIds = work.tags
        ? work.tags.split(',').map(Number).filter(Boolean)
        : [];

    // 封面回显
    if (work.coverFileUrl) {
      coverFiles.value = [
        {
          uid: `cover-${work.id}`,
          name: 'cover.jpg',
          status: 'done',
          url: work.coverFileUrl
        }
      ];
    }

    // 视频状态回显
    if (work.videoUrl) {
      hasVideo.value = true;
    }
  }
};

// 暴露open方法给父组件
defineExpose({ open });
</script>

<style scoped>
.cover-upload-container {
  display: flex;
  gap: 20px;
  align-items: flex-start;
}

.upload-placeholder {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  width: 180px;
  height: 100px;
  border: 1px dashed #ccc;
  border-radius: 4px;
  cursor: pointer;
  transition: border-color 0.3s;
}

.upload-placeholder:hover {
  border-color: #1890ff;
}

.upload-text {
  margin-top: 8px;
  color: #666;
  font-size: 14px;
}

.cover-upload-error {
  color: #ff4d4f;
  font-size: 12px;
  margin-top: 4px;
}

.tag-hint {
  margin: 8px 0 0;
  color: #666;
  font-size: 12px;
}

.video-hint {
  margin: 8px 0 0;
  color: #52c41a;
  font-size: 12px;
}

.ant-form-item {
  margin-bottom: 16px;
}
</style>
